package com.sec.etech.ism.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sec.etech.ism.model.IsmAppSetting;
import com.sec.etech.ism.model.IsmServiceDef;
import com.sec.etech.ism.service.*;
import com.sec.etech.ism.util.SapSignatureUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.openbpm.base.api.exception.BusinessMessage;
import org.openbpm.base.core.util.StringUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service
public class IsmSendWorkhour2sapServiceImpl implements IsmMethodService {

    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    IsmAppSettingService ismAppSettingService;
    @Resource
    IsmTaskService ismTaskService;
    @Resource
    IsmServiceDefService ismServiceDefService;
    @Resource
    IsmTaskLogService ismTaskLogService;
    @Resource
    IsmCommonService ismCommonService;

    public IsmSendWorkhour2sapServiceImpl(){}

    @Override
    public JSONObject call(String sysCode, String serviceCode, JSONObject businessParams){
        JSONObject result = new JSONObject();
        String msg = this.sendWorkhour2sap(sysCode, serviceCode, null, businessParams.toJSONString());
        result.put("flag", msg);
        result.put("msg", msg);
        return result;
    }

    /**
     * 发送路线卡工时到SAP
     * @param sysCode
     * @param serviceCode
     * @param businessCode
     * @param businessParams
     * @return
     */
    private String sendWorkhour2sap(String sysCode, String serviceCode, String businessCode, String businessParams) {
        String msg = "success";
        Map<String, String> logMap = new HashMap<>(5);
        //服务信息
        IsmServiceDef serviceDef = null;
        try{
            serviceDef = ismServiceDefService.getByCode(serviceCode);
            //调用的应用信息
            IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);

            String preUrl = ismCommonService.getSapPreUrl(appSetting.getAppAddress(), appSetting.getAppConfig());
            //先调用查询物料号的方法，检查物料号 /BAPI_MATERIAL_EXISTENCECHECK
            JSONObject busObj = JSONArray.parseObject(businessParams);
            List<Map<String, Object>> routeList = null;
            if(busObj.containsKey("processid")) {
                String sql = "select serial_num,material_no,partsid,plantaskid,process_type_id from spp_route_rev " +
                        "where active=1 and curr_ver=1 and material_no is not null and material_no!='' and material_no!='\' and processid=?";
                routeList = jdbcTemplate.queryForList(sql, busObj.getString("processid"));
                //金工路线卡需要包含无卡信息
                if(busObj.getBoolean("noCard")!=null && busObj.getBoolean("noCard")){
                    routeList = routeList!=null ? routeList : new ArrayList<>();
                    List<String> partsIdList = new ArrayList<>();
                    for(Map<String, Object> map:routeList){
                        if(map.get("partsid")!=null) {
                            partsIdList.add(map.get("partsid").toString());
                        }
                    }
                    List<Map<String, Object>> partsList = null;
                    sql = "select partsid,partsnum,parts_SAPnum material_no,'noCard' from prod_parts where original_componentid=? and active=1 ";
                    if(partsIdList.size()>0) {
                        sql = sql + "and partsid not in ({})";
                        sql = StrUtil.format(sql, CollUtil.join(partsIdList, ","));
                        partsList = jdbcTemplate.queryForList(sql, busObj.getString("plantaskid"));
                    }else{
                        partsList = jdbcTemplate.queryForList(sql, busObj.getString("plantaskid"));
                    }
                    if(partsList!=null && partsList.size()>0){
                        routeList.addAll(partsList);
                    }
                }
            }else if(busObj.containsKey("route_serial")){
                String sql = "select serial_num,material_no,partsid,plantaskid,process_type_id from spp_route_rev where active=1 and curr_ver=1 and serial_num=?";
                routeList = jdbcTemplate.queryForList(sql, busObj.getString("route_serial"));
            }else if(busObj.containsKey("wh_id")){
                String sql = "select wh_id,route_serial serial_num,material_no,partsid,plantaskid,proc_type as process_type_id  from proc_workhour_card where wh_id=?";
                routeList = jdbcTemplate.queryForList(sql, busObj.getString("wh_id"));
            }
            if(routeList!=null && routeList.size()>0){
                //批量检查物料号
                String materialNos = this.checkMaterialNoBatch(routeList, preUrl, businessCode, businessParams,
                        serviceDef, appSetting.getAppKey2(), sysCode, logMap);
                if(StringUtil.isEmpty(materialNos)){
                    return "工时信息推送SAP接口失败：物料号不存在！";
                }
                for(Map<String,Object> map:routeList) {
                    try {
                        //单个检查物料号
                        /*String url = preUrl + "/BAPI_MATERIAL_EXISTENCECHECK";
                        JSONObject sapParams = new JSONObject();
                        sapParams.put("MATERIAL", map.get("material_no"));
                        this.checkSapResult(url, sapParams, serviceDef, appSetting.getAppKey2(), businessCode, "BAPI_MATERIAL_EXISTENCECHECK");*/
                        if(StringUtil.isNotEmpty(map.get("material_no")) && materialNos.contains(map.get("material_no").toString())){
                            //调用sap删除工艺路线
                            logMap = new HashMap<>(5);
                            this.deleteWorkHourInfo(map.get("material_no").toString(), preUrl, businessCode, businessParams,
                                    serviceDef, appSetting.getAppKey2(), sysCode, logMap);
                            //调用sap创建工艺路线
                            logMap = new HashMap<>(5);
                            if(map.containsKey("noCard")){//无卡处理
                                String msgTmp = this.getWorkHourInfoNoCard(map, preUrl, businessCode, businessParams, serviceDef,
                                        appSetting.getAppKey2(), sysCode, logMap);
                                msg = "success".equals(msgTmp) ? msg : msgTmp;
                            }else {//有卡处理
                                String msgTmp = this.getWorkHourInfo(map.get("wh_id")!=null ? Long.parseLong(map.get("wh_id").toString()) : null,
                                        map.get("serial_num")!=null ? map.get("serial_num").toString() : "", preUrl,
                                        businessCode, businessParams, serviceDef, appSetting.getAppKey2(), sysCode, logMap,
                                        MapUtils.getString(map,"process_type_id"));
                                msg = "success".equals(msgTmp) ? msg : msgTmp;
                            }
                        }
                    }catch (BusinessMessage e){
                        ismTaskLogService.saveExceptionTaskLog(serviceDef.getCode(), serviceDef.getName(), logMap);
                        e.printStackTrace();
                        return "工时信息推送SAP接口异常：" + e.getMessage();
                    }catch (Exception e){
                        ismTaskLogService.saveExceptionTaskLog(serviceDef.getCode(), serviceDef.getName(), logMap);
                        e.printStackTrace();
                        return "工时信息推送SAP接口异常，请联系管理员处理！";
                    }
                }
            }
            return msg;
        }catch (Exception e){
            log.error("工时信息推送SAP接口异常。serviceDef.getCode()={}，serviceDef.getName()={}，logMap={}",
                    serviceDef.getCode(), serviceDef.getName(), logMap);
            e.printStackTrace();
            return "工时信息推送SAP接口异常，请联系管理员处理！";
        }
    }
    /**
     * 调用sap创建工艺路线
     * 字段说明http://webqas08.shanghai-electric.com/sjram/sap-function-detail/share?applicationCode=SQEtech
     &sapSystemCode=Q11&sapClientCode=211&sapUserCode=68300021&sapFunctionCode=ZBAPI_ROUTING_SG&secretKey=a612217929a1a19d49220691c333d28b
     **/
    private String getWorkHourInfo(Long whId, String routeSerial, String preUrl, String businessCode, String businessParams,
                                   IsmServiceDef serviceDef, String appKey, String sysCode, Map<String, String> logMap,
                                   String process_type_id
    ) throws Exception {

        List<Map<String, Object>> whCardList = null;
        if(whId!=null && whId>0) {
            String sql = "select whc.wh_id,whc.partsid,whc.plantaskid,whc.proc_type,whc.material_no,pt.parts_SAPnum,pt.partsnum," +
                    "pt.partsname,pc.component_SAPnum,pc.componentnum,pc.componentname,pt.unit_parts_gross_weight,pt.weight " +
                    "from proc_workhour_card whc left join prod_parts pt ON pt.partsid = whc.partsid " +
                    "LEFT JOIN prod_component pc ON pc.componentid = whc.plantaskid where whc.wh_id=?";
            whCardList = jdbcTemplate.queryForList(sql, whId);
        }else {
            String sql = "select whc.wh_id,whc.partsid,whc.plantaskid,whc.proc_type,whc.material_no,pt.parts_SAPnum,pt.partsnum," +
                    "pt.partsname,pc.component_SAPnum,pc.componentnum,pc.componentname,pt.unit_parts_gross_weight,pt.weight " +
                    "from proc_workhour_card whc left join prod_parts pt ON pt.partsid = whc.partsid " +
                    "LEFT JOIN prod_component pc ON pc.componentid = whc.plantaskid where whc.route_serial=?";
            whCardList = jdbcTemplate.queryForList(sql, routeSerial);
        }
        if (whCardList==null || whCardList.size()==0) {
            return "success";
        }
        String url = preUrl + "/ZBAPI_ROUTING_SG";
        logMap.put("appName", "ZBAPI_ROUTING_SG");
        logMap.put("url", url);
        JSONObject sapParams = new JSONObject();
        Long partsId = whCardList.get(0).get("partsid")!=null ? (Long) whCardList.get(0).get("partsid") : null;
        //组装ZTASK信息（物料描述）
        List<JSONObject> ztaskList = new ArrayList<>();
        JSONObject ztaskObj = new JSONObject();
        //装配的单位为套
        if (StringUtil.isNotEmpty(process_type_id) && "2".equals(process_type_id)) {
            ztaskObj.put("TASK_MEASURE_UNIT", "套");
        } else {
            ztaskObj.put("TASK_MEASURE_UNIT", "EA");
        }
        ztaskObj.put("PLANT", "1303");//工厂代号 1303和1301
        if(partsId!=null && partsId>0){
            ztaskObj.put("DESCRIPTION", whCardList.get(0).get("partsname"));//物料描述
        }else {
            ztaskObj.put("DESCRIPTION", whCardList.get(0).get("componentname"));//物料描述
        }
        ztaskObj.put("TASK_LIST_USAGE", "1");
        ztaskObj.put("VALID_FROM", "20070101");
        ztaskObj.put("TASK_LIST_STATUS", "4");
        ztaskList.add(ztaskObj);
        sapParams.put("ZTASK", ztaskList);
        sapParams.put("ZBOMUSAGE", "01");
        sapParams.put("ZAPPLICATION", "PP01");
        //组装MATERIAL信息（物料信息）
        List<JSONObject> materialList = new ArrayList<>();
        JSONObject materialObj = new JSONObject();
        materialObj.put("PLANT", "1303");//工厂代号 1303和1301
        materialObj.put("VALID_FROM", "20070101");//固定值
        materialObj.put("MATERIAL", whCardList.get(0).get("material_no"));//物料号
        materialList.add(materialObj);
        sapParams.put("MATERIAL", materialList);
        //组装ZOPERATION信息（工步工时信息）
        String sql = "select wh.step_num,wh.workhour as workinghours,wh.op_text,wh.workcenter,wh.worktype," +
                "wc.`code` AS workcentercode,wt.`name` AS worktypename " +
                "from proc_workhour_step wh LEFT JOIN proc_process_z_work_center wc ON wc.workcenter_id = wh.workcenter_id " +
                "LEFT JOIN proc_process_z_worktype wt ON wt.worktype_id = wh.worktype_id " +
                "where wh.active=1 and wh.wh_id=? order by wh.step_num";
        List<Map<String, Object>> whList = jdbcTemplate.queryForList(sql, whCardList.get(0).get("wh_id").toString());
        if (whList==null || whList.size()==0) {
            JSONObject result = this.checkSapResult(url, sapParams, serviceDef, appKey, businessCode, businessParams,
                    sysCode, "ZBAPI_ROUTING_SG", logMap);
            if(StringUtil.isEmpty(result.getString("message"))){
                return "success";
            }else {
                return result.getString("message");
            }
        }
        List<JSONObject> zoperationList = new ArrayList<>();
        for(Map<String, Object> map:whList){
            JSONObject mapObj = new JSONObject(map);
            JSONObject zoperationObj = new JSONObject();
            zoperationObj.put("ACTIVITY", mapObj.get("step_num"));//工序编号
            //工作中心
            String workCenterCode = mapObj.getString("workcentercode");
            if (StringUtil.isEmpty(workCenterCode)) {
                //工作中心没有取冗余的字段
                workCenterCode = mapObj.getString("workcenter");
            }
            zoperationObj.put("WORK_CNTR", workCenterCode);//工作中心
            //控制码 规则
            //PP02  —— WX-开头
            //PP06  —— 无工作中心
            //PP01  —— Q-开头，人工工时
            //PP01  —— 其他工作中心，机器工时
            //PP01  —— R-开头，热处理工时
            String controlCode = "";
            if (StringUtil.isEmpty(workCenterCode)) {
                controlCode = "PP06";
            }else if (workCenterCode.startsWith("WX-")) {
                controlCode = "PP02";
                //机器工时、人工工时、制造费用
                if (mapObj.get("workinghours")!=null) {
                    //机器工时相关
                    zoperationObj.put("ACTTYPE_01", "200");//活动类型
                    zoperationObj.put("STD_UNIT_01", "MIN");
                    zoperationObj.put("STD_VALUE_01", mapObj.get("workinghours"));//机器工时
                    //人工工时相关
                    zoperationObj.put("ACTTYPE_02", "100");//活动类型
                    zoperationObj.put("STD_UNIT_02", "MIN");
                    zoperationObj.put("STD_VALUE_02", mapObj.get("workinghours"));//人工工时
                    //制造费用相关
                    zoperationObj.put("ACTTYPE_03", "300");//活动类型
                    zoperationObj.put("STD_UNIT_03", "MIN");
                    zoperationObj.put("STD_VALUE_03", mapObj.get("workinghours"));//制造费用
                }
            }else if (workCenterCode.startsWith("Q-")) {
                //人工工时
                controlCode = "PP01";
                if (mapObj.get("workinghours") != null) {
                    //人工工时相关
                    zoperationObj.put("ACTTYPE_02", "100");//活动类型
                    zoperationObj.put("STD_UNIT_02", "MIN");
                    zoperationObj.put("STD_VALUE_02", mapObj.get("workinghours"));//人工工时
                    //制造费用相关
                    zoperationObj.put("ACTTYPE_03", "300");//活动类型
                    zoperationObj.put("STD_UNIT_03", "MIN");
                    zoperationObj.put("STD_VALUE_03", mapObj.get("workinghours"));//制造费用
                }
            }else if (workCenterCode.startsWith("R-") || "824-01L2".equals(workCenterCode)) {
                //热处理工时
                controlCode = "PP01";
                //热处理X 热处理工时的，应该读取关联零件的毛重数据
                Double unitPGWeight = null;
                if(whCardList.get(0).get("unit_parts_gross_weight")!=null) {
                    unitPGWeight = Double.parseDouble(whCardList.get(0).get("unit_parts_gross_weight").toString());
                }
                if (unitPGWeight != null && unitPGWeight.doubleValue() > 0) {
                    //热处理相关
                    zoperationObj.put("ACTTYPE_04", "400");//活动类型
                    zoperationObj.put("STD_UNIT_04", "KG");
                    zoperationObj.put("STD_VALUE_04", unitPGWeight.toString());//热处理
                } else if (whCardList.get(0).get("weight") != null) {
                    //热处理相关 毛重为空或为0的抓净重
                    zoperationObj.put("ACTTYPE_04", "400");//活动类型
                    zoperationObj.put("STD_UNIT_04", "KG");
                    zoperationObj.put("STD_VALUE_04", whCardList.get(0).get("weight").toString());//热处理
                }
            }else if(mapObj.get("workinghours")!=null){
                //机器工时
                controlCode = "PP01";
                //机器工时相关
                zoperationObj.put("ACTTYPE_01", "200");//活动类型
                zoperationObj.put("STD_UNIT_01", "MIN");
                zoperationObj.put("STD_VALUE_01", mapObj.get("workinghours"));//机器工时
                //人工工时相关
                zoperationObj.put("ACTTYPE_02", "100");//活动类型
                zoperationObj.put("STD_UNIT_02", "MIN");
                zoperationObj.put("STD_VALUE_02", mapObj.get("workinghours"));//人工工时
                //制造费用相关
                zoperationObj.put("ACTTYPE_03", "300");//活动类型
                zoperationObj.put("STD_UNIT_03", "MIN");
                zoperationObj.put("STD_VALUE_03", mapObj.get("workinghours"));//制造费用
            }
            zoperationObj.put("CONTROL_KEY", controlCode);//控制码
            //工序描述 (设备/工种数据)
            String worktypeName = mapObj.getString("worktypename");
            if (StringUtil.isEmpty(worktypeName)) {
                //设备/工种没有取冗余的字段
                worktypeName = mapObj.getString("worktype");
            }
            if (StringUtil.isNotEmpty(mapObj.getString("op_text"))) {
                zoperationObj.put("DESCRIPTION", worktypeName + "-" + mapObj.getString("op_text"));//工序描述
            }else {
                zoperationObj.put("DESCRIPTION", worktypeName);//工序描述
            }
            zoperationObj.put("BASE_QUANTITY", "1");//基本数量
            if (StringUtil.isNotEmpty(process_type_id) && "2".equals(process_type_id)) {
                zoperationObj.put("OPERATION_MEASURE_UNIT", "套");
            } else {
                zoperationObj.put("OPERATION_MEASURE_UNIT", "EA");
            }
            if("PP01".equals(controlCode)){
                zoperationObj.put("NOMINATOR", "1");
            }else if("PP02".equals(controlCode) || "PP06".equals(controlCode)){
                zoperationObj.put("NOMINATOR", "1");
                //外协 固定三列 成本要素-5001040000、采购组-317、物料组-908930
                if("PP02".equals(controlCode)){
                    zoperationObj.put("MATL_GROUP", "908930");
                    zoperationObj.put("PURCH_GROUP", "317");
                    zoperationObj.put("COST_ELEM", "5001040000");
                }
            }
            if(!"PP06".equals(controlCode)){
                zoperationObj.put("COST_RELEVANT", "X");
            }
            zoperationObj.put("DENOMINATOR", "1");
            zoperationObj.put("USERFIELD_CH20_00", "");
            zoperationObj.put("USERFIELD_CH20_01", "");
            zoperationObj.put("USERFIELD_CH10_02", "");
            zoperationObj.put("USERFIELD_CH10_03", "");
            zoperationList.add(zoperationObj);
        }
        sapParams.put("ZOPERATION", zoperationList);
        JSONObject result = this.checkSapResult(url, sapParams, serviceDef, appKey, businessCode, businessParams,
                sysCode,"ZBAPI_ROUTING_SG", logMap);
        if(StringUtil.isEmpty(result.getString("message"))){
            return "success";
        }else {
            return result.getString("message");
        }
    }

    //组装无卡信息
    private String getWorkHourInfoNoCard(Map<String, Object> routeMap, String preUrl, String businessCode, String businessParams,
                                         IsmServiceDef serviceDef, String appKey, String sysCode, Map<String, String> logMap) throws Exception{

        String url = preUrl + "/ZBAPI_ROUTING_SG";
        logMap.put("appName", "ZBAPI_ROUTING_SG");
        logMap.put("url", url);
        JSONObject sapParams = new JSONObject();
        //组装ZTASK信息（物料描述）
        List<JSONObject> ztaskList = new ArrayList<>();
        JSONObject ztaskObj = new JSONObject();
        ztaskObj.put("TASK_MEASURE_UNIT", "EA");
        ztaskObj.put("PLANT", "1303");//工厂代号 1303和1301
        ztaskObj.put("DESCRIPTION", routeMap.get("partsname"));//物料描述
        ztaskObj.put("TASK_LIST_USAGE", "1");
        ztaskObj.put("VALID_FROM", "20070101");
        ztaskObj.put("TASK_LIST_STATUS", "4");
        ztaskList.add(ztaskObj);
        sapParams.put("ZTASK", ztaskList);
        sapParams.put("ZBOMUSAGE", "01");
        sapParams.put("ZAPPLICATION", "PP01");
        //组装MATERIAL信息（物料信息）
        List<JSONObject> materialList = new ArrayList<>();
        JSONObject materialObj = new JSONObject();
        materialObj.put("PLANT", "1303");//工厂代号 1303和1301
        materialObj.put("VALID_FROM", "20070101");//固定值
        materialObj.put("MATERIAL", routeMap.get("material_no"));//物料号
        materialList.add(materialObj);
        sapParams.put("MATERIAL", materialList);
        //组装ZOPERATION信息（工步工时信息）
        List<JSONObject> zoperationList = new ArrayList<>();
        JSONObject zoperationObj = new JSONObject();
        zoperationObj.put("ACTIVITY", "0101");//工序编号
        zoperationObj.put("CONTROL_KEY", "PP06");//控制码
        zoperationObj.put("DESCRIPTION", "无卡");//物料描述
        zoperationObj.put("BASE_QUANTITY", "1");//基本数量
        zoperationObj.put("OPERATION_MEASURE_UNIT", "EA");//单位
        zoperationObj.put("NOMINATOR", "1");
        zoperationObj.put("DENOMINATOR", "1");
        zoperationObj.put("USERFIELDS_KEYWORD_ID", "PLM0001");
        zoperationObj.put("USERFIELD_CH20_00", "");
        zoperationObj.put("USERFIELD_CH20_01", "");
        zoperationObj.put("USERFIELD_CH10_02", "");
        zoperationObj.put("USERFIELD_CH10_03", "");
        zoperationList.add(zoperationObj);
        sapParams.put("ZOPERATION", zoperationList);
        JSONObject result = this.checkSapResult(url, sapParams, serviceDef, appKey, businessCode, businessParams,
                sysCode,"ZBAPI_ROUTING_SG", logMap);
        if(StringUtil.isEmpty(result.getString("message"))){
            return "success";
        }else {
            return result.getString("message");
        }
    }

    //批量检查物料号
    private String checkMaterialNoBatch(List<Map<String,Object>> objectList, String preUrl, String businessCode, String businessParams,
                                        IsmServiceDef serviceDef, String appKey, String sysCode, Map<String, String> logMap) throws Exception{

        String materialNos = "";//校验通过的物料号
        String notExistRoutes = "";//物料号不存在的路线卡
        String url = preUrl + "/ZBAPI_PLM_GET_MATERIAL2";
        logMap.put("appName", "ZBAPI_PLM_GET_MATERIAL2");
        logMap.put("url", url);
        if(objectList!=null && objectList.size()>0){
            JSONObject sapParams = new JSONObject();
            sapParams.put("I_DATE", DateUtil.format(new Date(), "yyyyMMdd"));
            List<JSONObject> jmaktList = new ArrayList<>(objectList.size());
            for(Map<String,Object> map:objectList) {
                JSONObject matnrObj = new JSONObject();
                matnrObj.put("MATNR",  map.get("material_no"));
                jmaktList.add(matnrObj);
            }
            sapParams.put("JMAKT", jmaktList);
            JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
            String body = JSONObject.toJSONString(bodyObj);
            logMap.put("input", body);
            int timeout = JSONObject.parseObject(serviceDef.getParams()).getInteger("timeout");
            long startTime = System.currentTimeMillis();
            String result = HttpUtil.post(url, body, timeout*60*1000);
            log.info("SAP系统ZBAPI_PLM_GET_MATERIAL2接口耗时：{}ms。", System.currentTimeMillis() - startTime);
            logMap.put("output", result);
            JSONObject resultObj = JSONObject.parseObject(result);
            if(resultObj.getBoolean("success") && resultObj.containsKey("data")) {
                List<JSONObject> resJmaktList = (List<JSONObject>) resultObj.getJSONObject("data").get("JMAKT");
                if(resJmaktList!=null && resJmaktList.size()>0){
                    Map<String, String> resMNoMap = new HashMap<>(resJmaktList.size());
                    for(JSONObject resObj:resJmaktList){
                        resMNoMap.put(resObj.getString("MATNR").trim(), resObj.getString("MATNR").trim());
                    }
                    for(Map<String,Object> map:objectList) {
                        if(StringUtil.isNotEmpty(map.get("material_no")) && resMNoMap.containsKey(map.get("material_no").toString())){
                            materialNos = materialNos + map.get("material_no").toString() + ",";
                        }else if(StringUtil.isNotEmpty(map.get("serial_num"))){
                            notExistRoutes = notExistRoutes + map.get("serial_num").toString() + ",";
                        }else if(StringUtil.isNotEmpty(map.get("partsnum"))){
                            notExistRoutes = notExistRoutes + map.get("partsnum").toString() + ",";
                        }
                    }
                }
            }
            Long taskId = null;
            String remark = null;
            if(StringUtil.isNotEmpty(notExistRoutes) || StringUtil.isEmpty(materialNos)) {
                if (StringUtil.isNotEmpty(notExistRoutes)) {
                    remark = "以下路线卡/零件物料号不存在：" + notExistRoutes.substring(0, notExistRoutes.length() - 1);
                } else {
                    remark = "所有路线卡/零件的物料号都不存在！";
                }
                taskId = ismTaskService.saveOrUpdateTask(sysCode, serviceDef.getCode(),
                        "ZBAPI_PLM_GET_MATERIAL2", businessParams);
            }else {//成功
                ismTaskService.deleteTaskByParams(sysCode, serviceDef.getCode(), "ZBAPI_PLM_GET_MATERIAL2",
                        businessCode, businessParams);
            }
            //保存接口调用日志
            JSONObject logObj = new JSONObject();
            logObj.put("task_id", taskId);
            logObj.put("service_code", serviceDef.getCode());
            logObj.put("service_name", serviceDef.getName());
            logObj.put("method_name", "ZBAPI_PLM_GET_MATERIAL2");
            logObj.put("request_url", url);
            logObj.put("input_json", bodyObj);
            logObj.put("output_json", result);
            logObj.put("message", remark);
            ismTaskLogService.saveLog(logObj);
        }
        return materialNos;
    }

    private void deleteWorkHourInfo(String materialNo, String preUrl, String businessCode, String businessParams,
                                      IsmServiceDef serviceDef,String appKey, String sysCode, Map<String, String> logMap) throws Exception{
        String url = preUrl + "/ZBAPI_ROUTING_DELETE";
        JSONObject sapParams = new JSONObject();
        sapParams.put("I_FACTORY", "1303");
        sapParams.put("I_MATNR", materialNo);
        logMap.put("appName", "ZBAPI_ROUTING_DELETE");
        logMap.put("url", url);
        this.checkSapResult(url, sapParams, serviceDef, appKey, businessCode, businessParams,
                sysCode, "ZBAPI_ROUTING_DELETE", logMap);
    }
    //检查sap返回结果，获取返回数据
    private JSONObject checkSapResult(String url, JSONObject sapParams, IsmServiceDef serviceDef, String appKey, String businessCode,
                                      String businessParams, String sysCode, String methodName, Map<String, String> logMap) throws Exception{

        JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
        String body = JSONObject.toJSONString(bodyObj);
        int timeout = JSONObject.parseObject(serviceDef.getParams()).getInteger("timeout");
        long startTime = System.currentTimeMillis();
        String result = HttpUtil.post(url, body, timeout*60*1000);
        log.info("SAP{}系统接口耗时：{}ms。", methodName, System.currentTimeMillis() - startTime);
        JSONObject resultObj = JSONObject.parseObject(result);

        JSONObject taskObj = new JSONObject();
        taskObj.put("sysCode", sysCode);
        taskObj.put("serviceCode", serviceDef.getCode());
        taskObj.put("methodName", methodName);
        taskObj.put("businessCode", businessCode);
        taskObj.put("businessParams", businessParams);
        taskObj.put("resultObj", resultObj);
        Long taskId = ismTaskService.checkAndSave(taskObj);
        //保存接口调用日志
        JSONObject logObj = new JSONObject();
        logObj.put("task_id", taskId);
        logObj.put("service_code", serviceDef.getCode());
        logObj.put("service_name", serviceDef.getName());
        logObj.put("method_name", methodName);
        logObj.put("request_url", url);
        logObj.put("input_json", bodyObj);
        logObj.put("output_json", result);
        JSONObject dataObj = resultObj!=null ? resultObj.getJSONObject("data") : null;
        String message = null;
        if(resultObj==null || !resultObj.getBoolean("success")) {
            message = resultObj!=null ? resultObj.getString("message") : "接口无返回数据，请检查接口和网络！";
        }else if(dataObj!=null && StringUtil.isNotEmpty(dataObj.getString("RETURN"))) {
            message = dataObj.getJSONObject("RETURN").getString("MESSAGE");
        }else if(dataObj!=null && StringUtil.isNotEmpty(dataObj.getString("RET"))) {
            message = dataObj.getJSONObject("RET").getString("MESSAGE");
        }
        if(taskId!=null && taskId>0) {
            message = StringUtil.isNotEmpty(message) ? message : "同步SAP工时失败，请联系管理员！";
            logObj.put("message", message);
        }
        logMap.put("input", body);
        logMap.put("output", result);
        ismTaskLogService.saveLog(logObj);
        if(dataObj!=null) {
            dataObj.put("message", message);
        }
        return dataObj;
    }

    @Override
    public String methodName(){
        return "sendWorkhour2sap";
    }
}
